home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Interactive Web Graphics with Shout 3D
/
Interactive Web Graphics With Shout 3D.iso
/
pc
/
Code
/
Chapter Code.exe
/
Chapter11
/
ScanTheSkiesPanel.java
< prev
Wrap
Text File
|
2000-07-26
|
7KB
|
250 lines
package applets;
import shout3d.*;
import shout3d.core.*;
import shout3d.math.*;
import custom_nodes.*; //for ScanTheSkiesDisplay
import java.applet.*; //for AudioClip
public class ScanTheSkiesPanel extends Shout3DPanel implements DeviceObserver {
//game state variables
boolean started = false;
boolean killed = false;
//screen pixels
int startPixelX;
int startPixelY;
//heads-Up display
ScanTheSkiesDisplay display;
int score = 0;
double startTime;
int elapsedSeconds;
//missile
int totalSeconds = 40;
float distance;
float speed = 10; //10 meters per second
float startDistance = 10.f * totalSeconds;
Transform child;
Transform parent;
float[] missileAxisAngle = new float[4];
float[] missileEulers = new float[3];
Quaternion missileQ = new Quaternion();
//gun
Transform gun;
float[] gunAxisAngle = new float[4];
float[] gunEulers = new float[3];
Quaternion gunQ = new Quaternion();
float headingSpeed = 0.0f;
float pitchSpeed = 0.0f;
Picker fire;
//animated explosion
TimeSensor detonator;
Transform explosion;
float [] intersection = new float[3];
AudioClip gong;
//the constructor
public ScanTheSkiesPanel (Shout3DApplet applet){
super(applet);
}
public void customInitialize() {
//get references to scene nodes
child = (Transform) getNodeByName("CHILD");
parent = (Transform) getNodeByName("PARENT");
detonator = (TimeSensor) getNodeByName("DETONATOR");
gun = (Transform) getNodeByName("GUN");
explosion = (Transform) getNodeByName("EXPLOSION");
display = (ScanTheSkiesDisplay) getNodeByName("DISPLAY");
gong = applet.getAudioClip(applet.getCodeBase(), "models/sounds/gong.au");
//register observers
addDeviceObserver(this, "MouseInput", null);
getRenderer().addRenderObserver(this, null);
//create a picker
fire = getNewPicker();
}
protected void finalize() {
removeDeviceObserver(this,"MouseInput");
getRenderer().removeRenderObserver(this);
}
public boolean onDeviceInput(DeviceInput di, Object userData) {
MouseInput mi = (MouseInput) di;
switch (mi.which) {
case MouseInput.DOWN:
if (started == false) {
//create missile to start
started = true;
newMissile();
}
if (killed) {
//if killed, reset score
score = 0;
display.score.setValue(score);
killed = false;
}
//in any case, store start of drag
startPixelX = mi.x;
startPixelY = mi.y;
return true;
case MouseInput.DRAG:
//set gun rotation speeds
//based on drag distances
int endPixelX = mi.x;
int endPixelY = mi.y;
int dragDistanceX = endPixelX - startPixelX;
int dragDistanceY = endPixelY - startPixelY;
headingSpeed = dragDistanceX/150f;
pitchSpeed = dragDistanceY/70f;
return true;
case MouseInput.UP:
//store intersection point
fire.setPickInfo(Picker.POINT, true);
//compute center of window
int centerPixelX = size().width/2;
int centerPixelY = size().height/2;
//fire the picker ray
Node [] results = fire.pickClosest(centerPixelX, centerPixelY);
//if ray hits something
if (results != null) {
//move explosion to intersection
//and detonate with sound
intersection = fire.getPickInfo(Picker.POINT);
explosion.translation.setValue(intersection);
detonator.start();
gong.play();
//increment the score
//and update the display
score++;
display.score.setValue(score);
//decrease missle start
//distance by 10, but not
//below 200 meters
if (totalSeconds > 20) {
totalSeconds--;
startDistance = 10.0f * totalSeconds;
}
//launch a new missile
newMissile();
}
//stop gun rotation
headingSpeed = 0.0f;
pitchSpeed = 0.0f;
return true;
}//end of switch
return false;
}//end of onDeviceInput()
public void onPreRender (Renderer r, Object o) {
//do nothing unless game is started
if (started) {
//compute current distance
//of missile from player
float delta = speed/getFramesPerSecond();
distance = distance - delta;
//end game if missile hits player
if (distance <= 0){
display.shotClock.setValue(0);
killed = true;
started = false;
totalSeconds = 40;
startDistance = 10.0f * totalSeconds;
return;
}
//if missile still moving,
//update its position
child.translation.set1Value(2, -distance);
//update gun rotation
float headingDelta = headingSpeed/getFramesPerSecond();
float pitchDelta = pitchSpeed/getFramesPerSecond();
gunEulers[0] = gunEulers[0] + headingDelta;
gunEulers[1] = gunEulers[1] + pitchDelta;
gunQ.setEulers(gunEulers);
gunQ.getAxisAngle(gunAxisAngle);
gun.rotation.setValue(gunAxisAngle);
//update shot clock
double currentTime = getAbsoluteTime();
elapsedSeconds = (int)(currentTime - startTime);
display.shotClock.setValue(totalSeconds - elapsedSeconds);
}//end of if started
}//end of onPreRender()
private void newMissile() {
//set random heading and pitch
missileEulers[0] = (float) (Math.random() * 6.28);
missileEulers[1] = (float) (Math.random() * 6.28);
missileQ.setEulers(missileEulers);
//rotate missile to start position
missileQ.getAxisAngle(missileAxisAngle);
parent.rotation.setValue(missileAxisAngle);
distance = startDistance;
child.translation.set1Value(2, -distance);
//reset clock
startTime = getAbsoluteTime();
}//end of newMissile()
} //end of class